package com.syedu.day03;

/**
 * @Description 运算符
 * @createTime 2022/3/7 9:06
 * @author Administrator
 */
public class OperationDemo {
    public static void main(String[] args) {
        /**
         *  算数运算符
         *  1.除法 /   乘法 *
         *  2.计算过程中数据不能超过该数据类型的最值,否则产生计算错误
         *  3.Java相同数据类型进行运算,结果是它本身,即数据类型不变
         *    Java不同数据类型进行运算,结果是偏向数据类型较大的一方
         *  4.加号是Java中具有两种功能的运算符
         *      a.数学加法
         *      b.字符串拼接
         *   加号两边都是数字类型时是数学运算,有字符串,则是拼接
         */
        System.out.println(2147483647 + 1);//计算溢出,结果不正确
        System.out.println(2147483647 + 1L);//结果正确

        System.out.println(2 + 1);//3
        System.out.println("2" + 1);//21
        System.out.println(2 + "1");//21
        System.out.println("2" + "1");//21

        System.out.println(2 - 3);
        System.out.println(2 * 3);
        System.out.println(9 / 2);//4
        System.out.println(9.0 / 2);//4.5
        System.out.println(9 / 2.0);//4.5
        System.out.println(9.0 / 2.0);//4.5
        System.out.println(9 % 4);

        System.out.println("-----------------------------------------");

        /**
         * 赋值运算符
         * 1. =     赋值
         * 2. ==    等于     判断符号两边的值是否相等(不比较类型)     boolean
         *          后面学习:
         *          基本类型比较值是否相等,不看类型
         *          对象类型比较内存地址
         */
        int i = 3;//把3赋值给变量i
        System.out.println(i == 3.0);

        /**
         * 与算数运算符结合使用
         * 1.简洁
         * 2.可以避免类型转换问题,但是计算结果有可能错误
         *
         * 注意: byte和short在数值直接赋值时,JVM内部会自动强制转换时类型匹配,
         *      不包含运算后赋值的情况!
         */
        byte b = 126;//byte b = (byte)126;
        short s = 100; //short s = (short)100;
        //b = b + 1;//编译错误
        b += 1;
        System.out.println(b);

        System.out.println("-----------------------------------------");

        /**
         * 自增++(前后),自减--(前后)
         * 表达式: 由变量和运算符所组成的合法语句
         * 表达式先运算符,则先计算,后赋值(前++/前--)
         * 表达式先变量,则先赋值,后计算(后++/后--)
         * 无论是前还是后,经过表达式后,值就已经发生改变了!
         */
        int a = 10;
        System.out.println(a++);//先赋值,后自增
        System.out.println(a);

        int bb = 10;
        System.out.println(++bb);//先自增,后赋值
        System.out.println(bb);

        /*int x = 10;
        int y = 20;
        //x++;后++
        //++x;//前++
        int r = x++ + ++x  + --y;
        System.out.println(r);*/

        /*int y = 10;
        int r= y-- + --y;
        System.out.println(r);*/

        System.out.println("-----------------------------------------");

        /**
         * 比较运算符,返回boolean类型
         */
        System.out.println(3 > 2);
        System.out.println(3 < 2);
        System.out.println(3 <= 2);
        System.out.println(3 >= 2);
        System.out.println(3 == 2);
        System.out.println(3 != 2);

        System.out.println("-----------------------------------------");

        /**
         * 逻辑运算符
         * 逻辑与   &&     并且,要求同真为真,有假就假
         * 逻辑或   ||     或者,只要有真,结果就为真
         * 逻辑非   !      取反,真变假,假变真
         *
         * 注意:
         * &&      短路型逻辑与
         * ||      短路型逻辑或
         *
         * &       非短路型逻辑与
         * |       非短路型逻辑或
         *
         * 注意: 两个版本最终结果是一样的,但是性能上可能存在差异
         * 短路型版本的写法,在某些条件下,会让符号后面的代码不执行,从而提高程序运行的效率
         * && 前面为假,后面不运行
         * || 前面为真,后面不运行
         */
        System.out.println(3 > 2 && 2 < 1);
        System.out.println(3 > 2 || 2 < 1);
        System.out.println(!true);

        //闰年判断条件,可以整除4,不能整数100或者可以被400整除
        int year = 2000;
        if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
            System.out.println(year + "是闰年");
        } else {
            System.err.println(year + "不是闰年");
        }

        System.out.println("-----------------------------");

        //按位运算符
        /**
         * 按位与:同0为0,同1为1,不同为0(同假为假,同真为真,有假就假)
         *      0111
         *   &  1010
         *   --------
         *      0010
         */
        System.out.println(7 & 10);//2

        /**
         * 按位或:同0为0,同1为1,不同为1(同假为假,同真为真,有真就真)
         *      0111
         *   |  1010
         *  --------
         *      1111
         */
        System.out.println(7 | 10);//15

        /**
         * 按位异或:相同为0,不同为1
         *      0111
         *  ^   1010
         *  --------
         *      1101
         *
         * 注意: 一个数连续异或同一个数两次,结果是它本身!
         */
        System.out.println(7 ^ 10);//13
        System.out.println(7 ^ 10 ^ 10);//7

        /**
         * 按位取反 : 0变1,1变0
         *
         * 公式   ~x = -(x + 1)
         */
        System.out.println(~7);//-8

        System.out.println("-----------------------------------------");

        /**
         * 位移运算:直接操作底层二进制,所以性能最高
         *
         * >>   带符号右移   二进制整体右移,左边补原有符号位,右边超出部分舍弃
         * <<   带符号左移   二进制整体左移,左边超过部分被舍弃,右边补0
         * >>>  无符号右移   二进制整体右移,左边总是以0填充,右边超出部分舍弃
         *
         * 注意:
         * 左移的本质是在后面补0,右移的本质是在前面补0或者1,所以
         * 不存在无符号左移的情况,因为<<<不就是<<
         */
        //题目: 请您以性能最高的方式计算2的4次方?
        System.out.println(2 << 3);//16

        System.out.println("-----------------------------------------");

        /**
         *  三目运算符     条件? 表达式1:表示2;       相当于if else
         */
        int score = 85;
        System.out.println(score > 60 ? "及格" : "不及格");

        /*if(score>60){
            System.out.println("及格");
        }else {
            System.out.println("不及格");
        }*/
    }
}
